﻿using System.Xml;
using System.Globalization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Marbles.Core.Web.Syndication.Atom
{
    public class AtomFeed : FeedBase, IEnumerable<AtomItem>, IFeed
    {

        public override FeedType FeedType { get { return FeedType.Atom; } }
        public override string ContentType { get { return "application/atom+xml"; } }

        public List<AtomAuthor> Contributor { get { return this._contributor; } }
        public List<string> Category { get { return this._Category; } }
        public string Copyright { get { return GetProperty("rights", string.Empty) as string; } set { SetProperty("rights", value); } }
        public Uri Icon { get { return GetProperty("icon", null) as Uri; } set { SetProperty("icon", value); } }
        public Uri Logo { get { return GetProperty("logo", null) as Uri; } set { SetProperty("logo", value); } }

        public string ID { get { return GetProperty("id", string.Empty) as string; } set { SetProperty("id", value); } }
        public AtomItem[] Items { get { return this.BaseItems.ToArray(typeof(AtomItem)) as AtomItem[]; } }
        public string SubTitle { get { return GetProperty("subtitle", string.Empty) as string; } set { SetProperty("subtitle", value); } }
        public Uri Link { get { return GetProperty("link", null) as Uri; } set { SetProperty("link", value); } }
        public List<AtomAuthor> Author { get { return this._Author; } }
        public DateTime Updated { get { return Convert.ToDateTime(GetProperty("updated", DateTime.MinValue)); } set { SetProperty("updated", value); } }
        public string Generator { get { return GetProperty("generator", "Marbles Web Platform") as string; } }

        private List<string> _Category = null;
        private List<AtomAuthor> _Author = null;
        private List<AtomAuthor> _contributor = null;

        public AtomFeed()
            : base()
        {
            this._contributor = new List<AtomAuthor>();
            this._Author = new List<AtomAuthor>();
            this._Category = new List<string>();
            this.Copyright = string.Empty;
            this.Icon = null;
            this.Logo = null;
            this.ID = Guid.NewGuid().ToString();
            this.Title = string.Empty;
            this.Link = null;
            this.SubTitle = string.Empty;
            this.Updated = DateTime.Now;
        }

        public override string ToString()
        {
            return this.ToXml().InnerXml;
        }

        public override XmlDocument ToXml()
        {
            XmlDocument doc = new XmlDocument();
            XmlNode channel = FeedHelper.CreateElement(doc, "feed", "", "http://www.w3.org/2005/Atom");

            foreach (string s in FeedProperties.Keys)
            {
                if (FeedProperties[s] != null)
                {
                    if (FeedProperties[s].GetType() == typeof(Uri)) { channel.AppendChild(FeedHelper.CreateElement(doc, s, ((Uri)FeedProperties[s]).OriginalString, "http://www.w3.org/2005/Atom")); }
                    if (FeedProperties[s].GetType() == typeof(CultureInfo)) { channel.AppendChild(FeedHelper.CreateElement(doc, s, ((CultureInfo)FeedProperties[s]).Name, "http://www.w3.org/2005/Atom")); }
                    if (FeedProperties[s].GetType() == typeof(AtomAuthor)) { channel.AppendChild(((AtomAuthor)FeedProperties[s]).ToXml(doc)); }
                    if (FeedProperties[s].GetType() == typeof(DateTime)) { channel.AppendChild(FeedHelper.CreateElement(doc, s, Convert.ToDateTime(FeedProperties[s]).ToString("r"), "http://www.w3.org/2005/Atom")); }
                    if (FeedProperties[s].GetType() == typeof(string)) { channel.AppendChild(FeedHelper.CreateElement(doc, s, ((string)FeedProperties[s]), "http://www.w3.org/2005/Atom")); }
                }
            }

            if (this._Author.Count > 0)
            {
                foreach (AtomAuthor Author in this._Author)
                {
                    channel.AppendChild(Author.ToXml(doc));
                }
            }

            if (this._contributor.Count > 0)
            {
                foreach (AtomAuthor Author in this._contributor)
                {
                    channel.AppendChild(Author.ToXml(doc, "contributor"));
                }
            }

            if (this._Category.Count > 0)
            {
                foreach (string s in this._Category)
                {
                    XmlElement item = FeedHelper.CreateElement(doc, "category", string.Empty, "http://www.w3.org/2005/Atom");
                    item.Attributes.Append(FeedHelper.CreateAttribute(doc, "term", s));
                    channel.AppendChild(item);
                }
            }

            foreach (AtomItem item in this.BaseItems)
            {
                channel.AppendChild(item.ToXml(doc));
            }

            doc.AppendChild(channel);
            return doc;
        }

        public int Add(AtomItem item)
        {
            return BaseItems.Add(item);
        }

        public IEnumerator<AtomItem> GetEnumerator()
        {
            return BaseItems.GetEnumerator() as IEnumerator<AtomItem>;
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return BaseItems.GetEnumerator();
        }

        public static System.Web.UI.HtmlControls.HtmlLink GetRSSFeedLink(string ID, Uri Url, string Title)
        {
            System.Web.UI.HtmlControls.HtmlLink lnk = new System.Web.UI.HtmlControls.HtmlLink();
            lnk.Href = Url.OriginalString;
            lnk.ID = ID;
            lnk.Attributes.Add("type", "application/atom+xml");
            lnk.Attributes.Add("rel", "alternate");
            lnk.Attributes.Add("title", Title);
            return lnk;
        }

    }
}
